package seqlist;

/**
 * 带头单链表(头节点不存储具体元素)
 */
public class SingleLinkedListWithHead {
    // 虚拟头节点
    private Node dummyHead = new Node(-1);
    // 单链表中具体节点的个数(不包含虚拟头节点)
    private int size;

    /**
     * 在任意位置插入一个元素
     * @param index
     * @param data
     */
    public void addIndex(int index,int data) {
        if (index < 0 || index > size) {
            System.err.println("add index illegal!");
            return;
        }
        // 此时index无论为何值，都存在前驱节点
        Node prev = dummyHead;
        for (int i = 0; i < index; i++) {
            prev = prev.next;
        }
        // prev就指向了待插入的前驱节点
        Node node = new Node(data);
        node.next = prev.next;
        prev.next = node;
        size ++;
    }

    public void addFirst(int data) {
        addIndex(0,data);
    }

    public void addLast(int data) {
        addIndex(size,data);
    }

    /**
     * 在任意位置删除节点
     * @param index
     * @return 删除前的节点值
     */
    public int removeIndex(int index) {
        if (index < 0 || index >= size) {
            System.err.println("remove index illegal!");
            return -1;
        }
        Node prev = dummyHead;
        // 先找到待删除节点的前驱
        for (int i = 0; i < index; i++) {
            prev = prev.next;
        }
        // prev就指向了待删除的前驱节点
        Node node = prev.next;
        prev.next = node.next;
        node.next = null;
        size --;
        return node.data;
    }

    public int removeFirst() {
        return removeIndex(0);
    }

    public int removeLast() {
        return removeIndex(size - 1);
    }

    @Override
    public String toString() {
        String ret = "";
        Node node = dummyHead.next;
        while (node != null) {
            ret += node.data + "->";
            node = node.next;
        }
        ret += "NULL";
        return ret;
    }

    public static void main(String[] args) {
        SingleLinkedListWithHead withHead = new SingleLinkedListWithHead();
        withHead.addFirst(1);
        withHead.addLast(2);
        withHead.addLast(3);
        withHead.addIndex(1,10);
        // 1->10->2->3
        System.out.println(withHead);
        System.out.println(withHead.removeIndex(2));
        System.out.println(withHead);
    }
}
